package com.fingard.dsp.bank.directbank.hsbc01;

import com.fingard.util.DateHelper;
import com.fingard.util.ForeignBankUtil;
import org.apache.commons.lang.StringUtils;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.reqrespobj.RequestBase;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.foreigncurrsingle.ReqForeignCurrSingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingle;
import com.fingard.dsp.bank.reqrespobj.single.detail.ReqPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.FtpPortClient;
import com.fingard.net.FtpReceiver;
import com.fingard.net.SftpPortClient;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @author XueJy on 2018/9/12.
 * @version 1.0
 */
public class HSBC01Base extends DirectBase {
    private static String _LogCode = "HSBC01";//默认等于线路代码
    private String TagStatus = "ACK";
    private String TagMT940 = "STMT";
    private String TagMT942 = "MT942";
    private String TagLOG = "LOG";
    private char splitflag = ',';//支付文件分割符
    // 国家Code
    private String CountryCode = "CN";
    // 传送号码
    private String SourceId = "CN";
    // 档案类型
    private String FileType = "PMT";
    //connect customer id ,provided by hsbc
    private String ConnectID = "ABC38877001";
    //HSBCnetID ,provided by hsbc
    private String HSBCnetID = "CNHBAPGCN006233472";
    private String tagendflag = "-";//交易分隔符

    //tag of MT940&MT942
    protected String tag20 = ":20:";
    protected String tag21 = ":21:";
    protected String tag25 = ":25:";
    protected String tag61 = ":61:";
    protected String tag86 = ":86:";

    //MT940
    protected String tag28 = ":28C:";
    protected String tag60F = ":60F:";
    protected String tag60M = ":60M:";
    protected String tag62F = ":62F:";
    protected String tag62M = ":62M:";
    protected String tag64 = ":64:";
    protected String tag65 = ":65:";

    //MT942
    protected String tag28C = ":28C:";
    protected String tag34F = ":34F:";
    //private String tag13 = ":13:";
    protected String tag13D = ":13D:";
    protected String tag90D = ":90D:";
    protected String tag90C = ":90C:";

    protected String splitFlag = "-";//内容分隔符
    //protected String startFlag = "";//解析内容起始符号
    //protected String endFlag = "";//解析内容终止符号

    DecimalFormat df = new DecimalFormat("0.00");
    private SimpleDateFormat sdfdatetime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");

    public static ForeignBankUtil foreignBankHelper=null;

    protected String getCharset() {
        return getBankConfig().getCharset("GBK");

    }

    void writePayCommonHeader(StringBuilder tmpMsg, ReqBatPayRec p_req1988) throws Exception {
        Date now = new Date();
        //Authorization Type 验证方式A-P
        String payHead = "IFH,IFILE,CSV,,,,,,A,1.0,,U801";
        String[] headMsgs = payHead.split(",");
        headMsgs[3] = getBankConfig().getMapValueByKey("params", "bkPtyId");
        headMsgs[4] = getBankConfig().getMapValueByKey("params", "HSBCnetCustomerID");
        headMsgs[5] = p_req1988.reqBatchNO;
        headMsgs[6] = sdf.format(now);
        headMsgs[7] = Format.Time8Format.format(now);
        //支付文件总行数
        headMsgs[10] = String.valueOf(Integer.parseInt(p_req1988.totalNum) + 2);
        for (String headMsg : headMsgs) {
            tmpMsg.append(headMsg).append(",");
        }
        tmpMsg.delete(tmpMsg.length() - 1, tmpMsg.length());
        tmpMsg.append("\r\n");
        //ACH-CR 付款
        String paybody = "BATHDR,ACH-CR,,,,,,,,@1ST@,,,CNY,,,,,,,,,,,,,,,N";
        String[] tmpPayMsg = paybody.split(",");
        tmpPayMsg[2] = p_req1988.totalNum;
        tmpPayMsg[10] = Format.Date8Format.format(new Date());
        tmpPayMsg[11] = ownActFormat(p_req1988.ownAct);
        tmpPayMsg[12] = convertCurToBank(p_req1988.ownCur);
        tmpPayMsg[13] = p_req1988.totalAmt;
        tmpPayMsg[20] = p_req1988.ownActName;
        tmpPayMsg[25] = "I" + p_req1988.smsCode + "0";
        tmpPayMsg[26] = p_req1988.reqBatchNO;
        for (String headMsg : tmpPayMsg) {
            tmpMsg.append(headMsg).append(",");
        }
        tmpMsg.delete(tmpMsg.length() - 3, tmpMsg.length());
        tmpMsg.append("\r\n");
    }

    void writePayBodyParams(StringBuilder tmpMsg, ReqBatPayRec p_req1988) throws Exception {
        while (p_req1988.readRecord()) {
            ReqPayRecDetail detail = p_req1988.readedDetail;
            String recbody = "SECPTY,,,,,,,,,,,,,,N,N";
            String[] tmpRecMsg = recbody.split(",");
            tmpRecMsg[1] = detail.recAct;
            //字段长度.char(28)
            tmpRecMsg[2] = detail.recName;
            //12位 2nd Party Identifier
            String askNumber = detail.askNumber.length() > 12 ? detail.askNumber.substring(detail.askNumber.length() - 12, detail.askNumber.length()) : detail.askNumber;
            tmpRecMsg[3] = askNumber;
            //decimal place: 123456789012.00 or MAX without decimal place: 12345678901234)
            tmpRecMsg[7] = detail.payAmount;
            //Second Party Reference
            tmpRecMsg[9] = detail.askNumber;
            tmpRecMsg[10] = "CNACH" + ownActFormat(p_req1988.ownAct);
            //保单号
            String notecodefield = getBankConfig().getValueAsString("notecode");
            String notecode = detail.srcXElement.getSingleTextNotNull(notecodefield);
            //保单号加用途
            tmpRecMsg[11] = notecode + "  " + detail.useType;
            tmpRecMsg[12] = detail.recBankName;
            for (String recMsg : tmpRecMsg) {
                tmpMsg.append(recMsg).append(",");
            }
            tmpMsg.delete(tmpMsg.length() - 1, tmpMsg.length());
            tmpMsg.append("\r\n");
        }
        tmpMsg.delete(tmpMsg.length() - 2, tmpMsg.length());
    }

    void writeEnds(XmlTextWriter xmlWriter) {
        xmlWriter.writeEndElement();
        xmlWriter.directWrite("</Document>");
    }

    void writeRecCommonHeader(XmlTextWriter xmlWriter, RequestBase request) throws Exception {

        String batchno = "";
        String totalNum = "";
        String totalAmt = "";
        String type = "";
        String header = "";
        if ("9188".equals(request.reqHeader.transType)) {
            ReqBatPayRec req = ((ReqBatPayRec) request);
            totalNum = req.totalNum;
            totalAmt = req.totalAmt;
            batchno = req.reqBatchNO;
            header = "CstmrDrctDbtInitn";
            type = "urn:iso:std:iso:20022:tech:xsd:pain.008.001.02";
        } else if ("1908".equals(request.reqHeader.transType)) {
            ReqSingle req = ((ReqSingle) request);
            batchno = req.reqHeader.reqSeqID;
            header = "CstmrCdtTrfInitn";
            type = "urn:iso:std:iso:20022:tech:xsd:pain.001.001.03";
            totalNum = "1";
            totalAmt = req.singleDetail.payAmount;
        }

        xmlWriter.writeStartDocByDeclaration("<?xml version = \"1.0\" encoding = \"UTF-8\" ?>");
        xmlWriter.writeStartDocByDeclaration("<Document xmlns=\"" + type + "\">");
        xmlWriter.writeStartElement(header);
        xmlWriter.writeStartElement("GrpHdr");
        xmlWriter.writeElementString("MsgId", batchno);
        xmlWriter.writeElementString("CreDtTm", sdfdatetime.format(new Date()));
        xmlWriter.writeStartElement("Authstn");
        //P151  AUTH-FDET-FSUM-ILEV
        xmlWriter.writeElementString("Cd", "AUTH");
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("NbOfTxs", totalNum);
        if (!"1908".equals(request.reqHeader.transType)) {
            xmlWriter.writeElementString("CtrlSum", totalAmt);
        }
        xmlWriter.writeStartElement("InitgPty");
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("OrgId");
        xmlWriter.writeStartElement("Othr");
        //网银账号 HSBC Connect Id
        xmlWriter.writeElementString("Id", getBankConfig().getMapValueByKey("params", "bkPtyId"));
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();

    }

    void writeRecBodyParams(XmlTextWriter xmlWriter, ReqBatPayRec p_req9188) throws Exception {
        p_req9188.readRecord();
        
    	boolean isAclife = getBankConfig().getValueAsBool("IsAclife");

        ReqPayRecDetail readedDetail = p_req9188.readedDetail;
        xmlWriter.writeStartElement("PmtInf");
        //收方信息
        xmlWriter.writeElementString("PmtInfId", p_req9188.reqBatchNO);
        xmlWriter.writeElementString("PmtMtd", "DD");
        xmlWriter.writeStartElement("PmtTpInf");
        //RTGS 实时 RealTimeGrossSettlementSystem  RTNS RealTimeNetSettlementSyste
        xmlWriter.writeStartElement("SvcLvl");
        xmlWriter.writeElementString("Cd", "NURG");
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("ReqdColltnDt", Format.Date10Format.format(new Date()));
        xmlWriter.writeStartElement("Cdtr");
        xmlWriter.writeElementString("Nm", readedDetail.recName);
        xmlWriter.writeStartElement("PstlAdr");
        xmlWriter.writeElementString("Ctry", "CN");
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("CdtrAcct");
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("Othr");
        xmlWriter.writeElementString("Id", ownActFormat(p_req9188.ownAct));

        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("Ccy", convertCurToBank(readedDetail.recCur));
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("CdtrAgt");
        xmlWriter.writeStartElement("FinInstnId");
        //收方具体银行名
        xmlWriter.writeElementString("Nm", readedDetail.recBankName);
        xmlWriter.writeStartElement("PstlAdr");
        xmlWriter.writeElementString("Ctry", "CN");
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        int num = 1;
        //付方信息
        do {
            readedDetail = p_req9188.readedDetail;
            xmlWriter.writeStartElement("DrctDbtTxInf");
            xmlWriter.writeStartElement("PmtId");
            xmlWriter.writeElementString("InstrId", readedDetail.askNumber);
            xmlWriter.writeElementString("EndToEndId", readedDetail.askNumber);
            xmlWriter.writeEndElement();
            xmlWriter.directWrite("<InstdAmt Ccy=\"" + convertCurToBank(p_req9188.readedDetail.payCur) + "\">" + p_req9188.readedDetail.payAmount + "</InstdAmt>");
            xmlWriter.writeStartElement("DrctDbtTx");
            xmlWriter.writeStartElement("MndtRltdInf");
            xmlWriter.writeElementString("FrstColltnDt", Format.Date10Format.format(new Date()));
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            xmlWriter.writeStartElement("DbtrAgt");
            xmlWriter.writeStartElement("FinInstnId");
            
            xmlWriter.writeElementString("Nm", readedDetail.payBankName,true);
            
            xmlWriter.writeStartElement("PstlAdr");
            xmlWriter.writeElementString("Ctry", "CN");
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            xmlWriter.writeStartElement("Dbtr");
            xmlWriter.writeElementString("Nm", readedDetail.payName);
            xmlWriter.writeStartElement("PstlAdr");
            xmlWriter.writeElementString("Ctry", "CN");
            xmlWriter.writeEndElement();
            xmlWriter.writeStartElement("Id");
            xmlWriter.writeStartElement("OrgId");
            xmlWriter.writeStartElement("Othr");
            //投保单号
            if(isAclife){
                xmlWriter.writeElementString("Id", readedDetail.cvv2);
            }else{
            	String notecodefield = getBankConfig().getValueAsString("notecode");
            	String notecode = readedDetail.srcXElement.getSingleTextNotNull(notecodefield);
            	xmlWriter.writeElementString("Id", notecode);
            }
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            xmlWriter.writeStartElement("DbtrAcct");
            xmlWriter.writeStartElement("Id");
            xmlWriter.writeStartElement("Othr");
            xmlWriter.writeElementString("Id", readedDetail.payAct);
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            xmlWriter.writeStartElement("RmtInf");
            if(isAclife){
            	xmlWriter.writeElementString("Ustrd", "保费"+num);
            }else{
            	xmlWriter.writeElementString("Ustrd", readedDetail.useType);
            }
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            num++;
        } while (p_req9188.readRecord());

        xmlWriter.writeEndElement();
    }

    void writeSingePayBodyParams(XmlTextWriter xmlWriter, ReqSingle p_req1908) throws Exception {
        ReqPayRecDetail detail = p_req1908.singleDetail;
        xmlWriter.writeStartElement("PmtInf");
        //收方信息
        xmlWriter.writeElementString("PmtInfId", p_req1908.reqHeader.transSeqID);
        xmlWriter.writeElementString("PmtMtd", "TRF");
        xmlWriter.writeStartElement("PmtTpInf");
//        //大小额判断
//        if (new BigDecimal(p_req1908.singleDetail.payAmount).compareTo(new BigDecimal(50000)) > 1) {
//            xmlWriter.writeElementString("InstrPrty", "HIGH");
//        } else {
//            xmlWriter.writeElementString("InstrPrty", "NORM");
//        }
        xmlWriter.writeStartElement("SvcLvl");
        //URGP (Urgent Payment)
        //SDVA (Same Day Value)
        //PRPT (EBA Priority Service)
        xmlWriter.writeElementString("Cd", "URGP");
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //付款执行时间
        xmlWriter.writeElementString("ReqdExctnDt", Format.Date10Format.format(new Date()));
        xmlWriter.writeStartElement("Dbtr");
        xmlWriter.writeElementString("Nm", detail.payName);

//        xmlWriter.writeStartElement("PstlAdr");
//        xmlWriter.writeElementString("Ctry", "CN");
//        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("DbtrAcct");
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("Othr");
        xmlWriter.writeElementString("Id", ownActFormat(detail.payAct));
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
//        xmlWriter.writeElementString("Ccy", convertCurToBank(detail.payCur));
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("DbtrAgt");
        xmlWriter.writeStartElement("FinInstnId");
        xmlWriter.writeElementString("BIC", "HSBCCNSH");
//        xmlWriter.writeElementString("Nm", detail.cnapsName);
        xmlWriter.writeStartElement("PstlAdr");
        xmlWriter.writeElementString("Ctry", "CN");
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //收方信息
        xmlWriter.writeStartElement("CdtTrfTxInf");
        xmlWriter.writeStartElement("PmtId");
//        xmlWriter.writeElementString("InstrId", detail.askNumber);
        xmlWriter.writeElementString("EndToEndId", detail.askNumber);
        xmlWriter.writeEndElement();
        //付款金额
        xmlWriter.writeStartElement("Amt");
        xmlWriter.directWrite("<InstdAmt Ccy=\"" + convertCurToBank(detail.payCur) + "\">" + detail.payAmount + "</InstdAmt>");
        xmlWriter.writeEndElement();
        //手续费承担 付方
        xmlWriter.writeElementString("ChrgBr", "DEBT");
        xmlWriter.writeStartElement("CdtrAgt");
        xmlWriter.writeStartElement("FinInstnId");
        xmlWriter.writeElementString("Nm", detail.cnapsName);
        xmlWriter.writeStartElement("PstlAdr");
        xmlWriter.writeElementString("Ctry", "CN");
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("Cdtr");
        xmlWriter.writeElementString("Nm", detail.recName);
        xmlWriter.writeStartElement("PstlAdr");
        xmlWriter.writeElementString("Ctry", "CN");
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("CdtrAcct");
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("Othr");
        xmlWriter.writeElementString("Id", detail.recAct);
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("RmtInf");
        String usage = "/VHVPS/+" + detail.abstractATS + "+" + detail.purpose;
        xmlWriter.writeElementString("Ustrd", usage);
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
    }


    public FtpReceiver sendToBank(String fullFilePath, String fileName, String dir) {
        FtpSet ftpSet = bankFront.getFtpSet("aclifeFtp");
        FtpReceiver ftpReceiver = null;
        FtpPortClient ftpPortClient = null;
        try {
            ftpPortClient = new FtpPortClient(ftpSet);
            ftpSet.upDir = ftpSet.getUpDir(dir);
            WriteBankLogLn("本地文件路径:" + fullFilePath);
            WriteBankLogLn("FTP服务器文件路径:" + ftpSet.upDir);
            WriteBankLogLn2("FTP服务器文件上传地址:" + ftpSet.serverIP + ":" + ftpSet.port);
            //FTP设置成被动模式
            ftpPortClient.setLocalPassiveMode();
            ftpReceiver = ftpPortClient.uploadFile(fullFilePath, fileName);
        } catch (Exception e) {
            if (ftpPortClient != null) {
                try {
                    ftpPortClient.disconnect();
                } catch (IOException ie) {
                    e.printStackTrace();
                    WriteBankLogLn(ie);
                }
            }
        }
        return ftpReceiver;
    }
    //直连汇丰环境
    public FtpReceiver sendToBanks(String fullFilePath, String fileName, String dir) throws IOException {
        FtpSet ftpSet = bankFront.getFtpSet("sftpserver1");
        FtpReceiver ftpReceiver = null;
        SftpPortClient sftpPortClient = null;
        try {
            sftpPortClient = new SftpPortClient(ftpSet);
            WriteBankLogLn("本地文件路径:" + fullFilePath);
            WriteBankLogLn("SFTP服务器文件路径:" + ftpSet.upDir);
            WriteBankLogLn2("SFTP服务器文件上传地址:" + ftpSet.serverIP + ":" + ftpSet.port);
            sftpPortClient.connectBySSH();
            ftpReceiver= sftpPortClient.uploadFile("", fullFilePath, fileName);
        } catch (Exception e) {
            if (sftpPortClient != null) {
                try {
                    sftpPortClient.disconnect();
                } catch (IOException ie) {
                    e.printStackTrace();
                    WriteBankLogLn(ie);
                }
            }
        }
        return ftpReceiver;
    }


    /**
     * 汇丰SFTP下载 只下载MT940 942
     */
    public FtpReceiver downloadFile() throws IOException {
        FtpReceiver receiver = null;
        FtpReceiver delReceive = null;

        String localPath = getCommonDataFileDirectory(new Date(), "HSHBC");
        FtpPortClient ftpPortClient = null;
        SftpPortClient sftpPortClient = null;
        try {
            FtpSet aeolftpSet = bankFront.getFtpSet("aclifeFtp");
            ftpPortClient = new FtpPortClient(aeolftpSet);
            Set<String> downDirList = aeolftpSet.listDownDir();
            //FTP交互模式
            ftpPortClient.setLocalPassiveMode();
            ftpPortClient.connect();
            String alDownList = localPath + File.separator + "alDown" + File.separator + "alDownList.txt";
            File file = new File(alDownList);
            if (!file.exists()) {
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }
                file.createNewFile();
            }
            //读取已下载文件列表
            String str = FileHelper.readFileText(alDownList, getCharset());
            if (str == null) {
                str = "";
            }
            StringBuilder newList = new StringBuilder("");
            for (String pFor : downDirList) {
                String downPath = aeolftpSet.getDownDir(pFor);
                ftpPortClient.list(downPath, false);
                for (String filePath : ftpPortClient.arFiles) {
                    //判断是否已经下载
                    if (!str.contains(filePath)) {
                        WriteBankLogLn("FTP远程文件路径:" + downPath);
                        WriteBankLogLn("FTP远程文件完整路径:" + filePath);
                        String fileLocalPath = localPath + File.separator + filePath.replace(downPath, "");
                        receiver = ftpPortClient.downloadFile(filePath, fileLocalPath);
                        if (!receiver.isCompleted) {
                            return receiver;
                        }
                        //MT940|942 全取.全删
                        if ("txn".equals(pFor)) {
                            delReceive=  ftpPortClient.deleteFile(filePath);
                            if (delReceive.isCompleted) {
                                WriteBankLogLn("成功删除文件:" + filePath);
                            }
                        }
                        //汇丰单笔ACK=收款ACK
                        if ("SingleAckHF".equals(pFor)) {
                            String  content = FileHelper.readFileText(fileLocalPath, getCharset());
                            StringBuilder tmpSbMsg = new StringBuilder();
                            XmlTextReader tmpBkReader = loadBankRespXmlReader(content, tmpSbMsg);
                            //ack解析
                            if (tmpBkReader != null) {
                                //单笔付款的ACK文件类型
                                String orgnlMsgNmId = tmpBkReader.getFirstText("/Document/CstmrPmtStsRpt/OrgnlGrpInfAndSts/OrgnlMsgNmId");
                                if ("pain.001.001.03".equals(orgnlMsgNmId)) {
                                    delReceive=   ftpPortClient.deleteFile(filePath);
                                    if (delReceive.isCompleted) {
                                        WriteBankLogLn("成功删除文件:" + filePath);
                                    }
                                }
                            }
                        }
                        //恒生单笔ACK=批付ACK
                        if ("SingleAckHS".equals(pFor)) {
                            String  content = FileHelper.readFileText(fileLocalPath, "UTF-8");
                            String[] ackres = content.split("\n");
                            String[] ackhead = ackres[0].split(",");
                            if (ackhead.length > 6 && "PP".equals(ackhead[5].trim())) {
                                delReceive=   ftpPortClient.deleteFile(filePath);
                                if (delReceive.isCompleted) {
                                    WriteBankLogLn("成功删除文件:" + filePath);
                                }
                            }
                        }
                        WriteBankLogLn("FTP下载文件本地保存:" + fileLocalPath);
                        newList.append(filePath);
                    }
                }
                ftpPortClient.arFiles.clear();
            }
            FileHelper.appendFile(alDownList, newList.toString(), getCharset());
            //本地文件分类
            sortFile(localPath);
        } catch (Exception e) {


        } finally {
            if (ftpPortClient != null) {
                try {
                    ftpPortClient.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                    WriteBankLogLn(e);
                }
            }
        }
        return receiver;
    }

    public  FtpReceiver  downFromHF() throws Exception {
        FtpReceiver receiver = null;
        String localPath = getCommonDataFileDirectory(new Date(), "HSHBC");
        FtpPortClient ftpPortClient = null;
        SftpPortClient sftpPortClient = null;

        //SFTP 汇丰处下载    删除
        FtpSet ftpSet = bankFront.getFtpSet("sftpserver");
        sftpPortClient = new SftpPortClient(ftpSet);
        WriteBankLogLn2("文件下载路径:" + ftpSet.downDir);
        File resultdir = new File(localPath);
        if (!resultdir.exists()) {
            resultdir.mkdirs();
        }
        //下载成功结果文件
        receiver = sftpPortClient.listFiles(ftpSet.downDir, 0);
        if (receiver.isCompleted) {
            String fileList = receiver.connMsg;
            String[] names = fileList.split(",");
            for (String name : names) {
                if (receiver.isCompleted) {
                    receiver = sftpPortClient.downloadFile("", name, localPath + File.separator + name);
                } else {
                    return receiver;
                }
            }
        }
        sortFile(localPath);
        return receiver;
    }


    private void sortFile(String localPath) throws ParseException {
        File f = new File(localPath);
        if (f.exists()) {
            File[] files = f.listFiles();
            for (File fromFile : files) {
                if (fromFile.isDirectory()) {
                    continue;
                }
                String filename = fromFile.getName();
                String receivePath = "nonSort";
                if (filename.startsWith("ACKSTD1")) {
                    //和收款重名
                    receivePath = EnumDirType.SingleAck.getValue();
                } else if (filename.startsWith("ACKIFILE")) {
                    receivePath = EnumDirType.PayAck.getValue();
                } else if (filename.startsWith("MT942CN")) {
                    receivePath = EnumDirType.MT942.getValue();
                } else if (filename.startsWith("STMTCN")) {
                    receivePath = EnumDirType.MT940.getValue();
                } else if (filename.contains("(")) {
                    //088-251418-011(20180903-1).csv
                    receivePath = EnumDirType.RecReport.getValue();
                } else if (filename.startsWith("STDK2CN")) {
                    receivePath = EnumDirType.PayReport.getValue();
                }
                //和收款重复
//                else if (filename.startsWith("ACKSTD1")) {
//                    receivePath = EnumDirType.RecAck.getValue()
//                }
                Date pathDate = null;
                //  STMTCN.EJ321.112901323472.511055915020.TXT
                String[] dateStr = filename.split("\\.");
                if (dateStr.length > 2) {
                    pathDate = Format.Date8Format.parse(getYear() + dateStr[2].substring(0, 4));
                    //940文件放到前一天的目录下
                    if (EnumDirType.MT940.getValue().equals(receivePath)) {
                        Calendar cal = Calendar.getInstance();
                        cal.setTime(pathDate);
                        cal.add(Calendar.DAY_OF_YEAR, -1);
                        pathDate = cal.getTime();
                    }
                } else {
                    int index = filename.indexOf("(");
                    pathDate = Format.Date8Format.parse(filename.substring(index + 1, index + 9));
                }

                File toFile = new File(getReceivePath(receivePath, pathDate) + File.separator + filename);
//                WriteBankLogLn("成功下载文件,本地路径:" + toFile.getPath());
                //拷贝文件 拷贝成功删除原文件
                try {
                    FileHelper.copyFile(fromFile, toFile);
                    if (!fromFile.delete()) {
                        WriteBankLogLn("已备份文件" + fromFile.toString() + " 删除失败,请手动删除");
                    }
                } catch (Exception e) {
                }
            }
        }
    }

    public String getReceivePath(String dir, Date date) {
        String receicePath = "";
        if (EnumDirType.MT940.getValue().equals(dir)) {
            receicePath = File.separator + "txn" + File.separator + "MT940";
        } else if (EnumDirType.MT942.getValue().equals(dir)) {
            receicePath = File.separator + "txn" + File.separator + "MT942";
        } else if (EnumDirType.PayAck.getValue().equals(dir)) {
            receicePath = File.separator + "batchPay" + File.separator + "ack";
        } else if (EnumDirType.PayReport.getValue().equals(dir)) {
            receicePath = File.separator + "batchPay" + File.separator + "report";
        } else if (EnumDirType.RecAck.getValue().equals(dir)) {
            receicePath = File.separator + "batchRec" + File.separator + "ack";
        } else if (EnumDirType.RecReport.getValue().equals(dir)) {
            receicePath = File.separator + "batchRec" + File.separator + "report";
        } else if (EnumDirType.SingleAck.getValue().equals(dir)) {
            receicePath = File.separator + "singlePay" + File.separator + "ack";
        } else {
            receicePath = File.separator + "nonSort";
        }
        String fullpath = "";
        fullpath = getCommonDataFileDirectory(date, "HSHBC") + receicePath;

        if (!new File(fullpath).exists()) {
            new File(fullpath).mkdirs();
        }
        return fullpath;

    }

    String getYear() {
        return String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
    }

    String getTrimPath(String p_path) {
        return StringHelper.trimEnd(p_path, File.separator);
    }

    //获取文件夹目录下所有文件名
    List<String> getDirectoryAllFileName(String balanceFilePath) {
        List<String> fileNames = new ArrayList<String>();
        File file = new File(balanceFilePath);
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) {
                fileNames.add(files[i].getName());
            }
        }
        return fileNames;
    }

    String convertCommaToPoint(String amount) {
        if (!StringUtils.isEmpty(amount)) {
            if (amount.indexOf('.') > -1) {
                //Do nothing
            } else if (amount.indexOf(',') > -1) {
                if (amount.indexOf(',') - amount.lastIndexOf(',') == 0) {
                    amount = amount.replace(',', '.');
                }
            }
        }
        return amount;
    }

    // 清除敏感字符
    protected String ClearSpecialChar(String str) {
        str.replaceAll("#", "");
        str.replaceAll(",", "?,");
        str.replaceAll("[?]", "??");
        return str;
    }

    protected boolean exportContentToFile(String content, String fullName) {
        if (StringHelper.isNullOrEmpty(content) || StringHelper.isNullOrEmpty(fullName)) {
            return false;
        }
        try {
            FileHelper.writeFile(fullName, content, getCharset());
            WriteBankLogLn2("写入文件：" + fullName + ",文件内容 \r\n" + content);
        } catch (Exception e) {
            WriteBankLogLn2("写入文件：" + fullName + "失败!");
            e.printStackTrace();
            return false;
        }
        return FileHelper.existFile(fullName);
    }

    /**
     * 拼接报文头
     *
     * @param uniqueFileCode 文件唯一码
     * @param recordCount    文件总行数
     * @return
     */
    protected StringBuilder PaymentXMLToFileHeader(String uniqueFileCode, int recordCount) {
        StringBuilder sb = new StringBuilder();
        sb.append("IFH,");//record type
        sb.append("IFILE,");//file format
        sb.append("CSV,");//file type
        //HSBC connect customer ID
        //customer ID provided by HSBC
        sb.append(getBankConfig().getValueAsString("customerID") + ",");
        //HSBC net customer ID
        //HSBC connect customer ID
        sb.append(getBankConfig().getValueAsString("netID") + ",");
        sb.append(uniqueFileCode + ",");//unique for each file
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/ddHH:mm:ss");
        String today = sdf.format(date).substring(0, 10);
        String toTime = sdf.format(date).substring(10);
        sb.append(today + ",");
        sb.append(toTime + ",");
        //授权类型，P：需要网银审批，A不需审批
        sb.append("A,");//Authorization Type
        sb.append("1.0,");//File Version
        sb.append(recordCount + ",");//包含文件头的所有记录数
        sb.append("U801");//Local Language Character Set
        sb.append("\r\n");//换行
        return sb;
    }

    /**
     * 拼接报文体
     *
     * @param p_req1908
     * @return
     */
    protected StringBuilder PaymentXmlToFileBody(ReqSingle p_req1908) {
        StringBuilder sb = new StringBuilder();
        sb.append("BATHDR,");//record type
        sb.append("LTR,");//instruction type
        sb.append("1,");//total number of instructions in batch
        sb.append("A_ref_001,");//batch reference
        sb.append(",");//filter
        sb.append(",");//filter
        sb.append(",");//filter
        sb.append(",");//filter
        sb.append(",");//filter
        sb.append("@1ST@,");//constant eye catcher
        sb.append(p_req1908.singleDetail.payDate.replaceAll("-", "") + ",");//付款日期 //value Date(YYYYMMDD)
        sb.append(p_req1908.singleDetail.payAct + ",");//付款账号 first party account
        sb.append("CNY,");//币种 transaction Currency
        sb.append(p_req1908.singleDetail.payAmount + ",");//付方金额 transaction Amount
        sb.append(",");//filter
        sb.append(",");//filter
        sb.append("CN,");//first party account county
        sb.append("HBAP,");//first party account institution
        sb.append("CNY,");//first party account currency
        sb.append(",");//payment amount in debit account currency
        //sb.append(",");//filter
        sb.append(ClearSpecialChar(p_req1908.singleDetail.payName) + ",");//付方姓名
        sb.append(",");// First Party Information Line 1
        sb.append(",");// First Party Information Line 2
        sb.append(",");// First Party Information Line 3
        sb.append(",");// First Party Information Line 4
        sb.append(",");//Payment Code
        sb.append(p_req1908.singleDetail.askNumber);//unique(Max 16 bytes) and no Chinese ??
        sb.append("\r\n");//换行
        sb.append("SECPTY,");//Record Type
        sb.append(p_req1908.singleDetail.recAct + ",");//Second Party Account Number
        sb.append(ClearSpecialChar(p_req1908.singleDetail.recName) + ",");////Second Party Name
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(p_req1908.singleDetail.payAmount + ",");//Second Party Transation Amount
        sb.append(p_req1908.singleDetail.payDate.replaceAll("-", "") + ",");//Entry Value Date(YYYYMMDD)
        sb.append(",");//Filler
        sb.append(",");//Information Line1
        sb.append(",");//Information Line2
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append("N,");//Advice Indicator
        sb.append("N,");//WHT Indicator
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append("@HVP@,");//Constant Eye Catcher
        sb.append(",");//Filler
        sb.append("CNY,");//payment Currency
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        //sb.append(",");//Filler
        String bankName=p_req1908.singleDetail.cnapsName;
        //银行名称最长22个中文字，前11个字放在37栏位，后11个字放在38栏位
        if(!"".equals(bankName) && bankName.length()>11){
            sb.append(bankName.substring(0,11)+ ",");//收方银行名
            sb.append(bankName.substring(12)+",");//银行名称第二行
        }else {
            sb.append(bankName+ ",");//收方银行名
            sb.append(",");//银行名称第二行
        }
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append(",");//Filler
        sb.append("CN,");//Beneficiary Bank Country
        sb.append(",");//Filler
        sb.append(ClearSpecialChar(p_req1908.singleDetail.purpose) + ",");//Payment Details Line 1
        sb.append(",");//Payment Details Line 2
        sb.append(",");//Payment Details Line 3
        sb.append(",");//Payment Details Line 4
        sb.append("OUR");//Details of Charges
        sb.append(",");//Filler
        sb.append("\r\n");//换行
        return sb;
    }

    private boolean ContainChinese(String str) {
        if (str == null) return false;
        for (char c : str.toCharArray()) {
            if (isChinese(c)) return true;// 有一个中文字符就返回
        }
        return false;
    }

    // 判断一个字符是否是中文
    private boolean isChinese(char c) {
        return c >= 0x4E00 && c <= 0x9FA5;// 根据字节码判断
    }

    /**
     * 校验文件是否符合要求
     * @param flag
     * @param fileName
     * @return
     */
    private boolean fileTypeCheck(String flag,String fileName){
        if(StringHelper.hasAnyChar(flag)){
            if(flag.contains(",")){
                String[] ackAry=flag.split(",");
                for(String ack:ackAry){
                    if(fileName.contains(ack)){
                        return true;
                    }
                }
            }else{
                if(fileName.contains(flag)){
                    return true;
                }
            }
        }
        return false;
    }

    protected void analysisFile(String fileName) {
        String date = Format.Date8Format.format(new Date());
        //解密之后的文件路径
        String decryptPath = getBankConfig().getValueAsString("DecryptPath") + File.separator;
        //解析成功的文件存放路径
        String successFilePath = getBankConfig().getValueAsString("SuccessFilePath") + File.separator + date + File.separator
                + "decrypt" + File.separator;
        FileHelper.mkdir(successFilePath);
        //解析失败的文件存放路径
        String exceptionPath = getBankConfig().getValueAsString("ExceptionFilePath") + File.separator + date + File.separator
                + "decrypt" + File.separator;
        FileHelper.mkdir(exceptionPath);
        //不处理的付款文件受理状态文件路径
        String untreatedPath = getBankConfig().getValueAsString("UntreatedFilePath") + File.separator + date + File.separator
                + "decrypt" + File.separator;
        FileHelper.mkdir(untreatedPath);
        String fullName = decryptPath + fileName;
        if (!FileHelper.existFile(fullName)) {
            return;
        }
        String[] result = null;
        WriteBankLogLn2("开始处理文件:" + fullName);
        try {
            String mt940Flag=getBankConfig().getMapValueByKey("dealWithFileMapping","MT940");
            String mt942Flag=getBankConfig().getMapValueByKey("dealWithFileMapping","MT942");
            String ackFlag=getBankConfig().getMapValueByKey("dealWithFileMapping","ACK");
            if (fileName.contains("NCN") || fileTypeCheck(mt942Flag,fileName)) {//MT942
                analysisMT942File(fullName);
                renameTo(fullName, successFilePath + fileName);
            } else if (fileName.contains("SCN") || fileTypeCheck(mt940Flag,fileName)) {//MT940
                analysisMT940File(fullName);
                renameTo(fullName, successFilePath + fileName);
            } else if(fileTypeCheck(ackFlag,fileName)){
                analysisAckFile(fullName);
                renameTo(fullName, successFilePath + fileName);
            }else {//其他文件，如XCN，OCA等
                renameTo(fullName, untreatedPath + fileName);
            }
        } catch (Exception e) {
            WriteBankLogLn("解析文件异常："+e);
            e.printStackTrace();
            renameTo(fullName, exceptionPath + fileName);
        }
    }

    protected void analysisAckFile(String fullName) throws Exception {
        String ackFilePath=StringHelper.trimEndFileSp(getBankConfig().getValueAsString("DealedPath"));
        String[] rspStatus=new String[]{"","",""};
        //判断文件存不存在，不存在就不处理
        String context2 = FileHelper.readFileText(fullName, getCharset());
        if (StringHelper.isNullOrEmpty(context2)) {
            WriteBankLogLn("文件解析失败：-------" + fullName);
            throw new Exception("读取文件内容异常：" + fullName);
        }
        WriteBankLogLn2("读取文件:" + fullName + "中的内容：\r\n" + context2);
        context2=context2.replaceAll(" ","").replaceAll("\r","")
                .replaceAll("\n","").replaceAll("\t","");
        //用,进行分组，判断下标为0的数组值：1失败；2进行判断
        String[] contentAry=context2.split(",");
        if(contentAry.length>12 && contentAry[3].length()==10){
            String payDate=DateHelper.convertD10toD8(contentAry[3]);//支付日期
            if("1".equals(contentAry[0])){//文件级：只有校验失败才会返回
                rspStatus[0]=contentAry[1];//付款流水号
                rspStatus[1]="RJCT";//状态码
                rspStatus[2]="文件级校验失败："+contentAry[12];//失败信息
                //生成ack处理文件
                getAckStatus(ackFilePath,payDate,rspStatus,"1");
                WriteBankLogLn("ack-Lv.1文件已处理");
            }else if("2".equals(contentAry[0]) && contentAry[contentAry.length-2].length()==2){//指令级
                rspStatus[0]=contentAry[2];//付款流水号
                if("00".equals(contentAry[contentAry.length-2])){
                    rspStatus[1]="ACCP";//状态码
                    rspStatus[2]="文件级校验成功："+contentAry[contentAry.length-1];
                }else {
                    rspStatus[1]="RJCT";//状态码
                    rspStatus[2]="文件级校验失败："+contentAry[12];
                }
                //生成ack处理文件
                getAckStatus(ackFilePath,payDate,rspStatus,"2");
                WriteBankLogLn("ack-Lv.2文件已处理");
            }else {
                WriteBankLogLn("文件数据不符合规则："+context2);
            }
        }else {
            WriteBankLogLn("文件数据不符合规则："+context2);
        }
    }

    protected void analysisMT940File(String fullName) throws Exception {
        //判断文件存不存在，不存在就不处理
        String context2 = FileHelper.readFileText(fullName, getCharset());
        if (StringHelper.isNullOrEmpty(context2)) {
            WriteBankLogLn("文件解析失败：-------" + fullName);
            throw new Exception("读取文件内容异常：" + fullName);
        }
        WriteBankLogLn2("读取文件:" + fullName + "中的内容：\r\n" + context2);
        String[] allContext = context2.toString().split(splitFlag);
        for (String context : allContext) {
            StringBuilder balanceContent = new StringBuilder();
            int tag61Start = context.indexOf(tag61);
            if (tag61Start>-1) {
                int tag62FStart = context.indexOf(tag62F);
                String allDetailContent = "";
                //如果有明细记录，就截取其中的明细长度，并去除原文中的明细长度
                if (tag61Start != -1) {
                    tag61Start += tag61.length();
                    allDetailContent = context.substring(tag61Start, tag62FStart);
                    context = context.replace(allDetailContent, "").replace(tag61, "");
                }
                int offset, endset;
                //获取账号
                offset = context.indexOf(tag25) + tag25.length();
                endset = context.indexOf(tag28);
                String accountNum = context.substring(offset, endset).trim();
                //获取日初余额
                offset = context.indexOf(tag60F) + tag60F.length();
                endset = context.indexOf(tag62F);
                String openBal = context.substring(offset, endset).replace(",", ".").trim();
                openBal = openBal.substring(10);
                openBal = amtCheck(openBal);
                offset = context.indexOf(tag62F) + tag62F.length();
                endset = context.indexOf(tag64);
                String banlanceEnd = context.substring(offset, endset).trim();
                //获取日期
                String date1 = "20" + banlanceEnd.substring(1, 7);
                //获取币种
                String cur = banlanceEnd.substring(7, 10);
                //获取日终余额
                String banlance = banlanceEnd.substring(10).replace(",", ".").trim();
                banlance = amtCheck(banlance);
                offset = endset + tag64.length();
                endset = context.indexOf(tag86);
                String availBal = context.substring(offset, endset).trim().substring(10).replace(",", ".").replace("-}", "").trim();
                availBal = amtCheck(availBal);
                //账号|币种|期终余额|可用余额|期初余额
                balanceContent.append(accountNum + "|").append(cur + "|").append(banlance + "|").append(availBal + "|").append(openBal);
                String dealedFile = getBankConfig().getValueAsString("DealedPath") + File.separator + date1 + File.separator
                        + "MT940" + File.separator + accountNum + "_7505.txt";
                FileHelper.writeFile(dealedFile, balanceContent.toString(), getCharset());
                WriteBankLogLn2("写入文件：" + dealedFile + ",文件内容 \r\n" + balanceContent.toString());
                //解析历史明细
                if (!StringHelper.isNullOrEmpty(allDetailContent)) {
                    dealTransDetail(allDetailContent.split(tag61), accountNum, openBal, date1, cur, "MT940");
                }
            }
        }
    }

    protected void analysisMT942File(String fullName) throws Exception {
        //判断文件存不存在，不存在就不处理
        String context2 = FileHelper.readFileText(fullName, getCharset());
        if (StringHelper.isNullOrEmpty(context2)) {
            WriteBankLogLn("文件解析失败：-------" + fullName);
            throw new Exception("读取文件内容异常：" + fullName);
        }
        WriteBankLogLn2("读取文件:" + fullName + "中的内容：\r\n" + context2);
        String[] allContext = context2.toString().split(splitFlag);
        for (String context : allContext) {
            StringBuilder balanceContent = new StringBuilder();
            int tag61Start = context.indexOf(tag61);
            if (tag61Start>-1) {
                int tag90DStart = context.indexOf(tag90D);
                String allDetailContent = "";
                if (tag61Start != -1) {
                    tag61Start += tag61.length();
                    allDetailContent = context.substring(tag61Start, tag90DStart);
                    context = context.replace(allDetailContent, "").replace(tag61, "");
                }
                int offset, endset;
                //获取账号
                offset = context.indexOf(tag25) + tag25.length();
                endset = context.indexOf(tag28);
                String accountNum = context.substring(offset, endset).trim();
                //账户当天的时间
                offset = context.indexOf(tag13D) + tag13D.length();
                endset = context.indexOf(tag90D);
                String date = "20" + context.substring(offset, endset).substring(0, 6);
                String date2 = context.substring(offset, endset).substring(0, 10);//用于余额更新判断
                String tranDate = Format.Date10Format.format(Format.Date8Format.parse(date));
                //获取出账总金额
                offset = context.indexOf(tag90D) + tag90D.length();
                endset = context.indexOf(tag90C);
                String outBal = context.substring(offset, endset);
                int startIndex=indexLength(outBal.replace(",","").trim());
                outBal = outBal.substring(startIndex + 1).replaceAll(",", ".")
                        .replaceAll("\r", "").replaceAll("\n", "");
                outBal = amtCheck(outBal);
                //获取入账总金额
                offset = context.indexOf(tag90C) + tag90C.length();
                endset = context.indexOf(tag86);
                String inBal = context.substring(offset, endset);
                startIndex=indexLength(inBal.replace(",","").trim());
                inBal = inBal.substring(startIndex+1).replaceAll(",", ".")
                        .replaceAll("\r", "").replaceAll("\n", "");
                inBal = amtCheck(inBal);
                //获取账户币种
                offset = context.indexOf(tag34F) + tag34F.length();
                String cur = context.substring(offset, offset + 3);
                //获取余额相关信息
                offset = context.indexOf(tag86) + tag86.length();
                //获取交易金额
                String balance = context.substring(offset);
                //期初余额
                offset = balance.indexOf("PLGC");
                endset = balance.indexOf("/CLGC");
                String openBal = balance.substring(offset + 4, endset).replace(",", ".").trim();
                openBal = amtCheck(openBal);
                //期末余额
                offset = balance.indexOf("/CAVC");
                String closeBal = balance.substring(endset + 5, offset).replace(",", ".").trim();
                closeBal = amtCheck(closeBal);
                //当前可用余额
                String availBal = balance.substring(offset + 5).replace(",", ".").replace("-}", "").trim();
                availBal = amtCheck(availBal);
                String dealedPath = getBankConfig().getValueAsString("DealedPath") + File.separator + date + File.separator
                        + "MT942" + File.separator + accountNum + "_7506.txt";
                //计算该账户上一次的当前余额：当前余额-入账+出账
                BigDecimal bigDecimal = new BigDecimal(closeBal);
                String lastBal = bigDecimal.add(new BigDecimal(outBal)).subtract(new BigDecimal(inBal)).toString();
                // 余额结果：账号|币种|当前余额|可用余额|期初余额|最后交易日期|文件生成时间|期初余额对应的日期
                if (FileHelper.existFile(dealedPath)) {
                    WriteBankLogLn2("文件：" + dealedPath + "已存在，开始对已存在文件进行处理");
                    String hisContent = FileHelper.readFileText(dealedPath, getCharset());
                    String[] hisBal = hisContent.split("\\|");
                    if (Double.valueOf(hisBal[hisBal.length - 2]) < Double.valueOf(date2)) {
                        WriteBankLogLn2("收到一个后生成的文件，除了期初余额和期初余额对应日期，与他都更新");
                        //收到一个后生成的文件，除了期初余额和期初余额对应日期，与他都更新
                        balanceContent.append(accountNum + "|").append(cur + "|").append(closeBal + "|").append(availBal + "|")
                                .append(hisBal[4] + "|").append(tranDate + "|").append(date2 + "|").append(hisBal[7]);
                        FileHelper.writeFile(dealedPath, balanceContent.toString(), getCharset());
                        WriteBankLogLn2("更新文件：" + dealedPath + ",文件内容 \r\n" + balanceContent.toString());
                    } else {
                        WriteBankLogLn2("收到一个先生成的文件，开始判断期初余额是否更新");
                        //收到一个先生成的文件，判断期初余额要不要更新
                        if (Double.valueOf(hisBal[hisBal.length - 1]) > Double.valueOf(date2)) {
                            // 余额结果：账号|币种|当前余额|可用余额|期初余额|最后交易日期|文件生成时间|期初余额对应的日期
                            balanceContent.append(hisBal[0] + "|").append(hisBal[1] + "|").append(hisBal[2] + "|").append(hisBal[3] + "|")
                                    .append(openBal + "|").append(hisBal[5] + "|").append(hisBal[6] + "|").append(date2);
                            FileHelper.writeFile(dealedPath, balanceContent.toString(), getCharset());
                            WriteBankLogLn2("更新文件：" + dealedPath + ",文件内容 \r\n" + balanceContent.toString());
                        }
                    }
                } else {
                    balanceContent.append(accountNum + "|").append(cur + "|").append(closeBal + "|").append(availBal + "|")
                            .append(openBal + "|").append(tranDate + "|").append(date2 + "|" + date2);
                    FileHelper.writeFile(dealedPath, balanceContent.toString(), getCharset());
                    WriteBankLogLn2("写入文件：" + dealedPath + ",文件内容 \r\n" + balanceContent.toString());
                }
                //解析明细
                if (!StringHelper.isNullOrEmpty(allDetailContent)) {
                    dealTransDetail(allDetailContent.split(tag61), accountNum, lastBal, date, cur, "MT942");
                }
            }
        }
    }

    /**
     * 对明细记录进行数据落地处理
     *
     * @param allDetailContent 明细记录
     * @param accountNum       账号
     * @param balance          上一笔交易后的可用余额
     * @param date             支付当天 yyyyMMdd
     * @param cur              币种
     * @param fileType         文件类型('MT940','MT942')
     * @throws Exception
     */
    public void dealTransDetail(String[] allDetailContent, String accountNum, String balance, String date, String cur, String fileType) throws Exception {
        BigDecimal decimal = new BigDecimal(balance);
        String file = "";
        if ("MT942".equals(fileType)) {
            file = getBankConfig().getValueAsString("DealedPath") + File.separator + date + File.separator +
                    fileType + File.separator + accountNum + "_7515.txt";
            WriteBankLogLn2("文件类型：" + fileType + ",创建明细文件:" + file);
        } else if ("MT940".equals(fileType)) {
            file = getBankConfig().getValueAsString("DealedPath") + File.separator + date + File.separator +
                    fileType + File.separator + accountNum + "_7516.txt";
            WriteBankLogLn2("文件类型：" + fileType + ",创建明细文件:" + file);
        } else {
            throw new Exception("fileType参数不规范：" + fileType);
        }
        StringBuilder transDetail = new StringBuilder();
        for (String detailUnit : allDetailContent) {
            String valueDate = "";//起息日期
            String tranDate = "";//交易日期
            String transAmt = "";//交易金额
            String cdFlag = "";//借贷标识
            String recAct = "";//对方账户
            String recName = "";//对方名称
            String recDetail = "";//备注
            String reqId = "";//付款请求流水号
            String[] detailsplit = detailUnit.split(tag86);//[0] tag61   [1] tag86
            //起息日期
            valueDate = "20" + detailsplit[0].substring(0, 6);
            valueDate = Format.Date10Format.format(Format.Date8Format.parse(valueDate));
            //交易日期
            tranDate = "20" + detailsplit[0].substring(0, 2) + detailsplit[0].substring(6, 10);
            tranDate = Format.Date10Format.format(Format.Date8Format.parse(tranDate));
            String tranTime = tranDate + " 00:00:00";
            //借贷标识 D C RC RD
            cdFlag = detailsplit[0].charAt(10) + "";
            if ("R".equals(cdFlag)) {
                cdFlag = detailsplit[0].substring(10, 11);
                if ("RC".equals(cdFlag)) {
                    cdFlag = "D";
                } else {
                    cdFlag = "C";
                }
            }
            //交易金额
            int index2 = detailsplit[0].indexOf("Y", 10);
            int index = detailsplit[0].indexOf(",", index2) + 3;
            transAmt = detailsplit[0].substring(index2 + 1, index).replace(",", ".");
            transAmt = amtCheck(transAmt);
            //付款请求流水号
            int num1 = detailsplit[0].indexOf(",", index2) + 7;
            int num2 = detailsplit[0].indexOf("//", num1);
            reqId = detailsplit[0].substring(num1, num2);

            detailsplit = detailsplit[1].split("/");
            List<String> list = Arrays.asList(detailsplit);
            //对方账户
            if (list.indexOf("AC") != -1) {
                recAct = list.get(list.indexOf("AC") + 1).trim();
                recAct = recAct.replaceAll("\r\n", "");
            } else {
                //借贷标识为C时，银行未返回对方账户
                recAct = "";
            }
            //对方名称
            if (list.indexOf("BENM") != -1) {
                recName = list.get(list.indexOf("BENM") + 1).trim();
                recName = recName.replaceAll("\r\n", "");
            }
            if (list.indexOf("ORDP") != -1) {
                recName = list.get(list.indexOf("ORDP") + 1).trim();
                recName = recName.replaceAll("\r\n", "");
            }
            //用途
            if (list.indexOf("REMI") != -1) {
                recDetail = list.get(list.indexOf("REMI") + 1).trim();
                recDetail = recDetail.replaceAll("\r\n", "");
            }
            //余额 D:借；C：贷
            if ("D".equals(cdFlag)) {
                decimal = decimal.subtract(new BigDecimal(transAmt));
            } else {
                decimal = decimal.add(new BigDecimal(transAmt));
            }
            //账号 | 币种 | 交易日期| 交易时间| 计息日期 | 交易金额 |借贷标识| 账户余额 |对方账号|
//                    对方户名 | 对方银行 |用途| 付款请求流水号
            DecimalFormat format = new DecimalFormat("0.00");
            String[] detail = new String[]{accountNum, cur, tranDate, tranTime, valueDate, transAmt, cdFlag, format.format(decimal), recAct, recName, "", recDetail, reqId};
            for (int i = 0; i < detail.length; i++) {
                if (i < detail.length - 1) {
                    transDetail.append(detail[i].replaceAll("[\\r\\n]", "") + "|");
                } else {
                    transDetail.append(detail[i].replaceAll("[\\r\\n]", "") + "\r\n");
                }
            }
        }
        FileHelper.appendFile(file, transDetail.toString(), getCharset());
        WriteBankLogLn2("追加文件：" + file + ",追加明细内容 \r\n" + transDetail.toString());
    }

    /**
     * 从sftp服务器下载文件
     *
     * @return
     * @throws Exception
     */
    public List<String> downloadFileIsQJ() throws Exception {
        List<String> fileList = new ArrayList<String>();
        String localhostSavePath = getBankConfig().getValueAsString("ReceiveFilePath");
        FileHelper.mkdir(localhostSavePath);
        FtpSet ftpSet = bankFront.getFtpSet("sftpserver");
        SftpPortClient sftpPortClient = new SftpPortClient(ftpSet);
        FtpReceiver receiver = sftpPortClient.downloadFilePrvkey("", localhostSavePath, getBankConfig().getValueAsString("privateKeyPaswd"));
        sftpPortClient.disconnect();
        if (!receiver.isCompleted) {
            WriteBankLogLn2("从银行下载的文件失败");
            return fileList;
        } else {
            if (StringHelper.isNullOrEmpty(receiver.connMsg)) {
                WriteBankLogLn2("从银行下载的文件数量：0");
                return fileList;
            }
            fileList = Arrays.asList(receiver.connMsg.split("\\|"));
            String fileStr = receiver.connMsg.replaceAll("\\|", "\r\n");
            WriteBankLogLn2("从银行下载的文件数量：" + fileList.size() + "下载的文件： \r\n" + fileStr);
        }
        return fileList;
    }

    /**
     * 上传文件到sftp服务器
     *
     * @param fullName
     * @return
     * @throws IOException
     */
    protected boolean uploadFileIsQJ(String fullName) throws IOException {
        File file = new File(fullName);
        FtpSet ftpSet = bankFront.getFtpSet("sftpserver");
        String upDir = ftpSet.upDir;
        String filename = StringHelper.trimEndFileSp(upDir) + File.separator + file.getName();
        filename = filename.replaceAll("\\\\", "/");
        FileInputStream inputStream = null;
        SftpPortClient sftpPortClient = null;
        try {
            inputStream = new FileInputStream(file);
            sftpPortClient = new SftpPortClient(ftpSet);
            sftpPortClient.connectBySSHPrvkey(getBankConfig().getValueAsString("privateKeyPaswd"));
            FtpReceiver receiver = sftpPortClient.uploadFile("", inputStream, filename);
            if (receiver.isCompleted) {
                WriteBankLogLn2("上传文件：" + filename + "成功");
            } else {
                WriteBankLogLn2("上传文件：" + filename + "失败，异常为："+receiver.connMsg);
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            WriteBankLogLn("上传文件失败", e);
            return false;
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            sftpPortClient.disconnect();
        }
        return true;
    }

    /**
     * 文件移到
     *
     * @param source 原地址
     * @param target 新地址
     * @return
     */
    protected boolean renameTo(String source, String target) {
        boolean flag = new File(source).renameTo(new File(target));
        if (flag) {
            WriteBankLogLn2("文件：" + source + " ---移动至---\r\n" + target + "  成功");
        } else {
            WriteBankLogLn2("文件：" + source + " ---移动至---\r\n" + target + "  失败");
        }
        return flag;
    }

    String ownActFormat(String act) {

        if (act.contains("-")) {
            return act.replace("-", "");
        } else {
            return act;
        }
    }

    protected String amtCheck(String amt) throws Exception {
        if (amt.startsWith(".")) {
            amt = "0" + amt;
        }
        if (amt.endsWith(".")) {
            amt = amt + "00";
        }
        amt=keepTwoDecimals(amt);
        return amt;
    }

    /**
     * 去掉小数点后两位的任何元素
     * @param amt
     * @return
     */
    public String keepTwoDecimals(String amt){
        if(amt.indexOf(".")+3<amt.length()){
            amt=amt.substring(0,amt.indexOf(".")+3);
        }
        return amt;
    }

    //遍历字符串最后一个字母出现的位置
    protected int indexLength(String str){
        char[] array = str.toCharArray();
        int indexLength=0;
        for (int i = array.length-1; i > 0; i--) {
            if (array[i] > 'a' && array[i] < 'z' || array[i] > 'A' && array[i] < 'Z') {
                indexLength=i;
                break;
            }
        }
        return indexLength;
    }

    protected static boolean isLetter(char c){
        if(((c>='a'&&c<='z')   ||   (c>='A'&&c<='Z'))){
            return true;
        }
        return false;
    }

    /**
     * 标识字段转换
     * @param context 内容
     * @param flag1 标识字段1
     * @param flag2 标识字段2
     * @return
     */
    protected String presenceFlag(String context,String flag1,String flag2){
        String flag="";
        if(StringHelper.hasAnyChar(context)){
            if(context.contains(flag1)){
                flag= flag1;
            }else if(context.contains(flag2)){
                flag= flag2;
            }
        }
        return flag;
    }

    protected void writeCommonHeader(XmlTextWriter xmlWriter) throws Exception {
        xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\""+getCharset()+"\"?>");
        xmlWriter.writeElementAttribute("Document","xmlns",
                "urn:iso:std:iso:20022:tech:xsd:pain.001.001.03\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance");
        xmlWriter.writeStartElement("CstmrCdtTrfInitn");
    }

    /**
     * 汇丰香港--付款报文
     * @param xmlWriter
     * @param reqForeignCurrSingle
     * @throws Exception
     */
    protected void writeFileContent(XmlTextWriter xmlWriter, ReqForeignCurrSingle reqForeignCurrSingle) throws Exception {
        xmlWriter.writeStartElement("GrpHdr");
        xmlWriter.writeElementString("MsgId", reqForeignCurrSingle.singleDetail.askNumber);
        String date = reqForeignCurrSingle.singleDetail.payDate + "T" + reqForeignCurrSingle.singleDetail.payTime;
        xmlWriter.writeElementString("CreDtTm", date);
        xmlWriter.writeStartElement("Authstn");
        xmlWriter.writeElementString("Cd", "AUTH");
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("NbOfTxs", "1");
        //xmlWriter.writeElementString("CtrlSum", reqForeignCurrSingle.singleDetail.payAmount);
        //发起方信息
        xmlWriter.writeStartElement("InitgPty");
        //xmlWriter.writeElementString("Nm", payName);
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("OrgId");
        xmlWriter.writeStartElement("Othr");
        xmlWriter.writeElementString("Id",getBankConfig().getValueAsString("customerID"));//客户号
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //付款信息
        xmlWriter.writeStartElement("PmtInf");
        xmlWriter.writeElementString("PmtInfId", reqForeignCurrSingle.singleDetail.askNumber);//流水号
        xmlWriter.writeElementString("PmtMtd", "TRF");
        //xmlWriter.writeElementString("BtchBookg", "FALSE");
        //xmlWriter.writeElementString("NbOfTxs", "1");
        //xmlWriter.writeElementString("CtrlSum", reqForeignCurrSingle.singleDetail.payAmount);
        //付款类型信息
        xmlWriter.writeStartElement("PmtTpInf");
        xmlWriter.writeElementString("InstrPrty", "NORM");//优先级HIGH高、NORM正常
        xmlWriter.writeStartElement("SvcLvl");
        //if("1".equals(reqForeignCurrSingle.singleDetail.paySpd) || "1".equals(reqForeignCurrSingle.singleDetail.sameCity)){
        xmlWriter.writeElementString("Cd", "URGP");//URGP紧急付款、SDVA当天
        //}else {
        //    xmlWriter.writeElementString("Cd", "SDVA");//
        //}
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        if(StringHelper.hasAnyChar(reqForeignCurrSingle.singleDetail.bookDate)){
            xmlWriter.writeElementString("ReqdExctnDt", reqForeignCurrSingle.singleDetail.bookDate);
        }else {
            xmlWriter.writeElementString("ReqdExctnDt", reqForeignCurrSingle.singleDetail.payDate);
        }
        //付款人信息
        xmlWriter.writeStartElement("Dbtr");
        String payName=reqForeignCurrSingle.singleDetail.payName;
        StringBuilder town=new StringBuilder();
        if(payName.length()>70){
            town.append(payName.substring(70)).append(" ");
            payName=payName.substring(0,70);
        }
        xmlWriter.writeElementString("Nm", payName);
        //地址
        String address=reqForeignCurrSingle.singleDetail.payAddr;
        town.append(address.contains("##")?address.substring(address.indexOf("##")+2).replaceAll("##",""):"");
        xmlWriter.writeStartElement("PstlAdr");
        xmlWriter.writeElementString("PstCd","HK");
        if(town!=null){
            xmlWriter.writeElementString("TwnNm", town.toString().trim());
        }
        String countryCode=reqForeignCurrSingle.singleDetail.payCtryCode;
        if(StringHelper.hasAnyChar(countryCode)){
            xmlWriter.writeElementString("CtrySubDvsn", "C".equals(countryCode)?"CN":countryCode);
            xmlWriter.writeElementString("Ctry", "C".equals(countryCode)?"CN":countryCode);
        }
        xmlWriter.writeEndElement();
        //addressDealWith(xmlWriter,reqForeignCurrSingle.singleDetail.payAddr,reqForeignCurrSingle.singleDetail.payCtryCode,new StringBuilder());
        xmlWriter.writeEndElement();
        //付款人账户信息
        xmlWriter.writeStartElement("DbtrAcct");
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("Othr");
        xmlWriter.writeElementString("Id", reqForeignCurrSingle.singleDetail.payAct);
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //xmlWriter.writeElementString("Ccy", getBankConfig().getMapKeyByValue("payCurMapping",reqForeignCurrSingle.singleDetail.payAct));
        xmlWriter.writeEndElement();
        //付款人银行信息
        xmlWriter.writeStartElement("DbtrAgt");
        xmlWriter.writeStartElement("FinInstnId");
        xmlWriter.writeElementString("BIC", reqForeignCurrSingle.singleDetail.paySWIFTCODE);
        //地址
        xmlWriter.writeStartElement("PstlAdr");
        String payCtryCode=reqForeignCurrSingle.singleDetail.payCounyeryCode;
        if("C".equals(payCtryCode) || "156".equals(payCtryCode)){
            payCtryCode="CN";
        }
        if(StringHelper.hasAnyChar(payCtryCode)){
            xmlWriter.writeElementString("CtrySubDvsn",payCtryCode);
            xmlWriter.writeElementString("Ctry", payCtryCode);
        }
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //收款方交易信息
        xmlWriter.writeStartElement("CdtTrfTxInf");
        xmlWriter.writeStartElement("PmtId");
        xmlWriter.writeElementString("InstrId", reqForeignCurrSingle.singleDetail.askNumber);
        xmlWriter.writeElementString("EndToEndId", reqForeignCurrSingle.singleDetail.askNumber);
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("Amt");
        String currency = convertCurToBank(reqForeignCurrSingle.singleDetail.payCur);
        xmlWriter.writeElementAttribute("InstdAmt",reqForeignCurrSingle.singleDetail.payAmount,"Ccy",currency);
        xmlWriter.writeEndElement();
        xmlWriter.writeElementStringNotNull("ChrgBr", FeeBearer(reqForeignCurrSingle.singleDetail.costMode));
        if(StringHelper.hasAnyChar(reqForeignCurrSingle.singleDetail.recAgentBnkSWIFT)){
            xmlWriter.writeStartElement("IntrmyAgt1");
            xmlWriter.writeStartElement("FinInstnId");
            xmlWriter.writeElementString("BIC", reqForeignCurrSingle.singleDetail.recAgentBnkSWIFT);
            if(StringHelper.hasAnyChar(reqForeignCurrSingle.singleDetail.recAgentBnkName)){
                xmlWriter.writeElementString("Nm",reqForeignCurrSingle.singleDetail.recAgentBnkName);
            }
            if(StringHelper.hasAnyChar(reqForeignCurrSingle.singleDetail.recAgentBnkCtryCode)){
                xmlWriter.writeStartElement("PstlAdr");
                xmlWriter.writeElementString("CtrySubDvsn",reqForeignCurrSingle.singleDetail.recAgentBnkCtryCode);
                xmlWriter.writeElementString("Ctry",reqForeignCurrSingle.singleDetail.recAgentBnkCtryCode);
                xmlWriter.writeEndElement();
            }
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
        }
        //收款人银行信息
        xmlWriter.writeStartElement("CdtrAgt");
        xmlWriter.writeStartElement("FinInstnId");
        xmlWriter.writeElementString("BIC", reqForeignCurrSingle.singleDetail.recSWIFTCODE);
        xmlWriter.writeElementString("Nm", reqForeignCurrSingle.singleDetail.recBnkName);
        //地址
        String recBnkAddr=reqForeignCurrSingle.singleDetail.recBnkAddr;
        //String trwn=recBnkAddr.contains("##")?recBnkAddr.substring(recBnkAddr.indexOf("##")+2).replaceAll("##",""):"";
        xmlWriter.writeStartElement("PstlAdr");
        //if(StringHelper.hasAnyChar(trwn)){
        //    xmlWriter.writeElementString("TwnNm", trwn);
        //}
        String recCountryCode=reqForeignCurrSingle.singleDetail.recCountryCode;
        if("C".equals(recCountryCode) || "156".equals(recCountryCode)){
            recCountryCode="CN";
        }
        if(StringHelper.hasAnyChar(recCountryCode)){
            xmlWriter.writeElementString("CtrySubDvsn", recCountryCode);
            xmlWriter.writeElementString("Ctry", recCountryCode);
        }
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //收款人信息
        xmlWriter.writeStartElement("Cdtr");
        String recName=reqForeignCurrSingle.singleDetail.recName;
        String addline="";
        if(recName.length()>70){
            addline=recName.substring(70);
            recName=recName.substring(0,70);
        }
        xmlWriter.writeElementString("Nm", recName);
        //地址
        String recCtryCode=reqForeignCurrSingle.singleDetail.recCtryCode;
        if("C".equals(recCtryCode) || "156".equals(recCtryCode)){
            recCtryCode="CN";
        }
        String recAddress=reqForeignCurrSingle.singleDetail.recAddr;
        String city=recAddress.contains("##")?recAddress.substring(0,recAddress.indexOf("##")).replaceAll("##","").trim():recAddress.trim();
        String twnNm=recAddress.contains("##")?recAddress.substring(recAddress.indexOf("##")+2).replaceAll("##","").trim():"";
        StringBuilder sbd=new StringBuilder((addline+" "+twnNm));
        if(StringHelper.hasAnyChar(city)){
            //剩余可用总长度
            int cdtrLength=140-(reqForeignCurrSingle.singleDetail.recName.length()+recCtryCode.length()*2+twnNm.length());
            //twnNm剩余长度
            int recLength=35-sbd.toString().length();
            if(recLength>0 && cdtrLength>0){
                //还可容纳长度
                int index=0;
                if(cdtrLength>=recLength){
                    index=recLength;
                }else {
                    index=cdtrLength;
                }
                //往twnNm中继续添加
                if(index>0 && (index-1)>=city.length()){
                    if(sbd.toString().indexOf(twnNm)>0){
                        twnNm=sbd.insert(sbd.toString().indexOf(twnNm),city+" ").toString();
                    }else {
                        twnNm=sbd.toString();
                    }
                }else if(index>1){
                    if(sbd.toString().indexOf(twnNm)>0){
                        twnNm=sbd.insert(sbd.toString().indexOf(twnNm),city.substring(0,index-1)+" ").toString();
                    }else {
                        twnNm=sbd.toString();
                    }
                }
            }else{
                twnNm=sbd.toString().trim();
            }
        }else{
            twnNm=sbd.toString().trim();
        }
        xmlWriter.writeStartElement("PstlAdr");
        if(StringHelper.hasAnyChar(twnNm)){
            xmlWriter.writeElementString("TwnNm", twnNm.trim());
        }
        if(StringHelper.hasAnyChar(recCtryCode)){
            xmlWriter.writeElementString("CtrySubDvsn", recCtryCode);
            xmlWriter.writeElementString("Ctry", recCtryCode);
        }
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("CdtrAcct");
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("Othr");
        xmlWriter.writeElementString("Id", reqForeignCurrSingle.singleDetail.recAct);
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        String purpose=reqForeignCurrSingle.singleDetail.purpose;
        String ustrd="";//用途
        String prtry="";//补充
        if(StringHelper.hasAnyChar(purpose)){
            if(purpose.contains("##")){
                ustrd=purpose.substring(0,purpose.indexOf("##"));
                prtry=purpose.substring(purpose.indexOf("##")+2);
            }else {
                ustrd=purpose;
            }
            if(StringHelper.hasAnyChar(prtry)){
                xmlWriter.writeStartElement("RgltryRptg");
                xmlWriter.writeStartElement("Dtls");
                xmlWriter.writeElementString("Inf","/BUSINESS/"+prtry);
                xmlWriter.writeEndElement();
                xmlWriter.writeEndElement();
            }
            if(StringHelper.hasAnyChar(ustrd)){
                xmlWriter.writeStartElement("RmtInf");
                xmlWriter.writeElementString("Ustrd",ustrd);
                xmlWriter.writeEndElement();
            }
        }
        xmlWriter.writeEndDocument();
    }

    /**
     * 汇丰中国--境内外币付款报文
     * @param xmlWriter
     * @param reqForeignCurrSingle
     * @throws Exception
     */
    protected void writeFileContentCN(XmlTextWriter xmlWriter, ReqForeignCurrSingle reqForeignCurrSingle) throws Exception {
        xmlWriter.writeStartElement("GrpHdr");
        xmlWriter.writeElementString("MsgId", reqForeignCurrSingle.singleDetail.askNumber);
        String date = reqForeignCurrSingle.singleDetail.payDate + "T" + reqForeignCurrSingle.singleDetail.payTime;
        xmlWriter.writeElementString("CreDtTm", date);
        xmlWriter.writeStartElement("Authstn");
        xmlWriter.writeElementString("Cd", "AUTH");
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("NbOfTxs", "1");
        xmlWriter.writeElementString("CtrlSum", reqForeignCurrSingle.singleDetail.payAmount);
        //发起方信息
        xmlWriter.writeStartElement("InitgPty");
        String payName=reqForeignCurrSingle.singleDetail.payName;
        if(payName.length()>140){
            payName=payName.substring(0,140);
        }
        xmlWriter.writeElementString("Nm", payName);
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("OrgId");
        xmlWriter.writeStartElement("Othr");
        xmlWriter.writeElementString("Id",getBankConfig().getValueAsString("customerID"));//客户号
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //付款信息
        xmlWriter.writeStartElement("PmtInf");
        xmlWriter.writeElementString("PmtInfId", reqForeignCurrSingle.singleDetail.askNumber);//流水号
        xmlWriter.writeElementString("PmtMtd", "TRF");
        //xmlWriter.writeElementString("BtchBookg", "FALSE");
        //xmlWriter.writeElementString("NbOfTxs", "1");
        //xmlWriter.writeElementString("CtrlSum", reqForeignCurrSingle.singleDetail.payAmount);
        //付款类型信息
        xmlWriter.writeStartElement("PmtTpInf");
        //xmlWriter.writeElementString("InstrPrty", "NORM");//优先级HIGH高、NORM正常
        xmlWriter.writeStartElement("SvcLvl");
        xmlWriter.writeElementString("Cd", "URGP");//URGP紧急付款、SDVA当天
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        if(StringHelper.hasAnyChar(reqForeignCurrSingle.singleDetail.bookDate)){
            xmlWriter.writeElementString("ReqdExctnDt", reqForeignCurrSingle.singleDetail.bookDate);
        }else {
            xmlWriter.writeElementString("ReqdExctnDt", reqForeignCurrSingle.singleDetail.payDate);
        }
        //付款人信息
        xmlWriter.writeStartElement("Dbtr");
        xmlWriter.writeElementString("Nm", reqForeignCurrSingle.singleDetail.payName);
        //地址
        String ctryCode=reqForeignCurrSingle.singleDetail.payCtryCode;
        if(StringHelper.isNullOrEmpty(ctryCode) || "C".equals(ctryCode) || "156".equals(ctryCode)){
            ctryCode="CN";
        }
        addressDealWith(xmlWriter,reqForeignCurrSingle.singleDetail.payAddr,ctryCode,new StringBuilder());
        xmlWriter.writeEndElement();
        //付款人账户信息
        xmlWriter.writeStartElement("DbtrAcct");
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("Othr");
        xmlWriter.writeElementString("Id", reqForeignCurrSingle.singleDetail.payAct);
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("Ccy", convertCurToBank(reqForeignCurrSingle.singleDetail.payCur));
        xmlWriter.writeEndElement();
        //付款人银行信息
        xmlWriter.writeStartElement("DbtrAgt");
        xmlWriter.writeStartElement("FinInstnId");
        if(StringHelper.hasAnyChar(reqForeignCurrSingle.singleDetail.paySWIFTCODE)){
            xmlWriter.writeElementString("BIC", reqForeignCurrSingle.singleDetail.paySWIFTCODE);
        }else {
            xmlWriter.writeElementString("BIC", "HSBCCNSH");
        }
        //地址
        xmlWriter.writeStartElement("PstlAdr");
        String payCtryCode=reqForeignCurrSingle.singleDetail.payCounyeryCode;
        if(StringHelper.isNullOrEmpty(payCtryCode) || "C".equals(payCtryCode) || "156".equals(payCtryCode)){
            payCtryCode="CN";
        }
        xmlWriter.writeElementString("Ctry", payCtryCode);
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //收款方交易信息
        xmlWriter.writeStartElement("CdtTrfTxInf");
        xmlWriter.writeStartElement("PmtId");
        xmlWriter.writeElementString("InstrId", reqForeignCurrSingle.singleDetail.askNumber);
        xmlWriter.writeElementString("EndToEndId", reqForeignCurrSingle.singleDetail.askNumber);
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("Amt");
        String currency = convertCurToBank(reqForeignCurrSingle.singleDetail.recCur);
        xmlWriter.writeElementAttribute("InstdAmt",reqForeignCurrSingle.singleDetail.payAmount,"Ccy",currency);
        xmlWriter.writeEndElement();
        String chrgBr=FeeBearer(reqForeignCurrSingle.singleDetail.costMode);
        if(StringHelper.isNullOrEmpty(chrgBr)){
            chrgBr="DEBT";
        }
        xmlWriter.writeElementStringNotNull("ChrgBr", chrgBr);
        if(StringHelper.hasAnyChar(reqForeignCurrSingle.singleDetail.recAgentBnkSWIFT)){
            xmlWriter.writeStartElement("IntrmyAgt1");
            xmlWriter.writeStartElement("FinInstnId");
            xmlWriter.writeElementString("BIC", reqForeignCurrSingle.singleDetail.recAgentBnkSWIFT);
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
        }
        //收款人银行信息
        xmlWriter.writeStartElement("CdtrAgt");
        xmlWriter.writeStartElement("FinInstnId");
        if(StringHelper.hasAnyChar(reqForeignCurrSingle.singleDetail.recSWIFTCODE)){
            xmlWriter.writeElementString("BIC", reqForeignCurrSingle.singleDetail.recSWIFTCODE);
        }else {
            xmlWriter.writeElementString("BIC", "HSBCCNSH");
        }
        String recBnkName=reqForeignCurrSingle.singleDetail.recBnkName;
        if(StringHelper.isNullOrEmpty(recBnkName)){
            recBnkName=reqForeignCurrSingle.singleDetail.recCNAPSName;
        }
        if(recBnkName.length()>140){
            recBnkName=recBnkName.substring(0,140);
        }
        xmlWriter.writeElementString("Nm", recBnkName);
        //地址
        String recBnkAddr=reqForeignCurrSingle.singleDetail.recBnkAddr;
        String recBnkCtry=reqForeignCurrSingle.singleDetail.recCountryCode;
        if(StringHelper.isNullOrEmpty(recBnkCtry) || "C".equals(recBnkCtry) || "156".equals(recBnkCtry)){
            recBnkCtry="CN";
        }
        addressDealWith(xmlWriter,recBnkAddr,recBnkCtry,new StringBuilder());
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //收款人信息
        xmlWriter.writeStartElement("Cdtr");
        xmlWriter.writeElementString("Nm", reqForeignCurrSingle.singleDetail.recName);
        //地址
        String recCtry=reqForeignCurrSingle.singleDetail.recCtryCode;
        if(StringHelper.isNullOrEmpty(recCtry) || "C".equals(recCtry) || "156".equals(recCtry)){
            recCtry="CN";
        }
        addressDealWith(xmlWriter,reqForeignCurrSingle.singleDetail.recAddr,recCtry,new StringBuilder());
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("CdtrAcct");
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("Othr");
        xmlWriter.writeElementString("Id", reqForeignCurrSingle.singleDetail.recAct);
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        String ustrd=reqForeignCurrSingle.singleDetail.purpose;//用途
        if(StringHelper.hasAnyChar(ustrd)){
            xmlWriter.writeStartElement("RmtInf");
            xmlWriter.writeElementString("Ustrd","/INV/"+ustrd);
            xmlWriter.writeEndElement();
        }
        xmlWriter.writeEndDocument();
    }

    /**
     * 汇丰中国--境内人民币付款报文
     * @param xmlWriter
     * @param p_req1908
     * @throws Exception
     */
    protected void writeFileContent(XmlTextWriter xmlWriter,ReqSingle p_req1908) throws Exception {
        xmlWriter.writeStartElement("GrpHdr");
        xmlWriter.writeElementString("MsgId", p_req1908.singleDetail.askNumber);
        String date = p_req1908.singleDetail.payDate + "T" + p_req1908.singleDetail.payTime;
        xmlWriter.writeElementString("CreDtTm", date);
        xmlWriter.writeStartElement("Authstn");
        xmlWriter.writeElementString("Cd", "AUTH");
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("NbOfTxs", "1");
        xmlWriter.writeElementString("CtrlSum", p_req1908.singleDetail.payAmount);
        //发起方信息
        xmlWriter.writeStartElement("InitgPty");
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("OrgId");
        xmlWriter.writeStartElement("Othr");
        xmlWriter.writeElementString("Id",getBankConfig().getValueAsString("customerID"));//客户号
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //付款信息
        xmlWriter.writeStartElement("PmtInf");
        xmlWriter.writeElementString("PmtInfId", p_req1908.singleDetail.askNumber);//流水号
        xmlWriter.writeElementString("PmtMtd", "TRF");
        //xmlWriter.writeElementString("BtchBookg", "FALSE");
        //xmlWriter.writeElementString("NbOfTxs", "1");
        //xmlWriter.writeElementString("CtrlSum", p_req1908.singleDetail.payAmount);
        //付款类型信息
        xmlWriter.writeStartElement("PmtTpInf");
        //xmlWriter.writeElementString("InstrPrty", "NORM");//优先级HIGH高、NORM正常
        xmlWriter.writeStartElement("SvcLvl");
        xmlWriter.writeElementString("Cd", "URGP");//URGP紧急付款、SDVA当天
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        if(StringHelper.hasAnyChar(p_req1908.singleDetail.bookDate)){
            xmlWriter.writeElementString("ReqdExctnDt", p_req1908.singleDetail.bookDate);
        }else {
            xmlWriter.writeElementString("ReqdExctnDt", p_req1908.singleDetail.payDate);
        }
        //付款人信息
        xmlWriter.writeStartElement("Dbtr");
        String payName=p_req1908.singleDetail.payName;
        if(payName.length()>140){
            payName=payName.substring(0,140);
        }
        xmlWriter.writeElementString("Nm", payName);
        xmlWriter.writeStartElement("PstlAdr");
        xmlWriter.writeElementString("Ctry", "CN");
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //付款人账户信息
        xmlWriter.writeStartElement("DbtrAcct");
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("Othr");
        xmlWriter.writeElementString("Id", p_req1908.singleDetail.payAct);
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("Ccy", convertCurToBank(p_req1908.singleDetail.payCur));
        xmlWriter.writeEndElement();
        //付款人银行信息
        xmlWriter.writeStartElement("DbtrAgt");
        xmlWriter.writeStartElement("FinInstnId");
        xmlWriter.writeElementString("BIC","HSBCCNSH");//固定swiftcode
        //地址
        xmlWriter.writeStartElement("PstlAdr");
        xmlWriter.writeElementString("Ctry", "CN");
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //收款方交易信息
        xmlWriter.writeStartElement("CdtTrfTxInf");
        xmlWriter.writeStartElement("PmtId");
        xmlWriter.writeElementString("InstrId", p_req1908.singleDetail.askNumber);
        xmlWriter.writeElementString("EndToEndId", p_req1908.singleDetail.askNumber);
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("Amt");
        String currency = convertCurToBank(p_req1908.singleDetail.recCur);
        xmlWriter.writeElementAttribute("InstdAmt",p_req1908.singleDetail.payAmount,"Ccy",currency);
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("ChrgBr","DEBT");//默认DEBT
        //收款人银行信息
        xmlWriter.writeStartElement("CdtrAgt");
        xmlWriter.writeStartElement("FinInstnId");
        if(StringHelper.hasAnyChar(p_req1908.singleDetail.recSwiftCode)){
            xmlWriter.writeElementString("BIC", p_req1908.singleDetail.recSwiftCode);
        }
        String recBnkName=p_req1908.singleDetail.cnapsName;
        if(recBnkName.length()>140){
            recBnkName=recBnkName.substring(0,140);
        }
        xmlWriter.writeElementString("Nm", recBnkName);
        //地址
        xmlWriter.writeStartElement("PstlAdr");
        xmlWriter.writeElementString("Ctry", "CN");
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //收款人信息
        xmlWriter.writeStartElement("Cdtr");
        xmlWriter.writeElementString("Nm", p_req1908.singleDetail.recName);
        //地址
        xmlWriter.writeStartElement("PstlAdr");
        xmlWriter.writeElementString("Ctry", "CN");
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeStartElement("CdtrAcct");
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("Othr");
        xmlWriter.writeElementString("Id", p_req1908.singleDetail.recAct);
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        String ustrd=p_req1908.singleDetail.purpose;//用途
        if(StringHelper.hasAnyChar(ustrd)){
            xmlWriter.writeStartElement("RmtInf");
            xmlWriter.writeElementString("Ustrd",ustrd);
            xmlWriter.writeEndElement();
        }
        xmlWriter.writeEndDocument();
    }

    /**
     * 汇丰中国--境内外币付款报文
     * @param xmlWriter
     * @param p_req1988
     * @throws Exception
     */
    protected void writeFileContentCNBatch(XmlTextWriter xmlWriter, ReqBatPayRec p_req1988) throws Exception {
        xmlWriter.writeStartElement("GrpHdr");
        xmlWriter.writeElementString("MsgId", p_req1988.reqBatchNO);
        String date = p_req1988.payDate + "T" + p_req1988.payTime;
        xmlWriter.writeElementString("CreDtTm", date);
        xmlWriter.writeStartElement("Authstn");
        xmlWriter.writeElementString("Cd", "AUTH");
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("NbOfTxs", p_req1988.totalNum);
        //xmlWriter.writeElementString("CtrlSum", p_req1988.totalAmt);
        //发起方信息
        xmlWriter.writeStartElement("InitgPty");
        String payName=p_req1988.ownActName;
        if(payName.length()>140){
            payName=payName.substring(0,140);
        }
        xmlWriter.writeElementString("Nm", payName);
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("OrgId");
        xmlWriter.writeStartElement("Othr");
        xmlWriter.writeElementString("Id",getBankConfig().getValueAsString("customerID"));//客户号
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //付款信息
        xmlWriter.writeStartElement("PmtInf");
        xmlWriter.writeElementString("PmtInfId", p_req1988.reqBatchNO);//流水号
        xmlWriter.writeElementString("PmtMtd", "TRF");
        //xmlWriter.writeElementString("BtchBookg", "FALSE");
        //xmlWriter.writeElementString("NbOfTxs", "1");
        //xmlWriter.writeElementString("CtrlSum", reqForeignCurrSingle.singleDetail.payAmount);
        //付款类型信息
        xmlWriter.writeStartElement("PmtTpInf");
        //xmlWriter.writeElementString("InstrPrty", "NORM");//优先级HIGH高、NORM正常
        xmlWriter.writeStartElement("SvcLvl");
        xmlWriter.writeElementString("Cd", "URGP");//URGP紧急付款、SDVA当天
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("ReqdExctnDt", p_req1988.payDate);
        //付款人信息
        xmlWriter.writeStartElement("Dbtr");
        xmlWriter.writeElementString("Nm", p_req1988.ownActName);
        //地址
        xmlWriter.writeStartElement("PstlAdr");
        xmlWriter.writeElementString("Ctry", "CN");
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        //付款人账户信息
        xmlWriter.writeStartElement("DbtrAcct");
        xmlWriter.writeStartElement("Id");
        xmlWriter.writeStartElement("Othr");
        xmlWriter.writeElementString("Id", p_req1988.ownAct);
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeElementString("Ccy", convertCurToBank(p_req1988.ownCur));
        xmlWriter.writeEndElement();
        //付款人银行信息
        xmlWriter.writeStartElement("DbtrAgt");
        xmlWriter.writeStartElement("FinInstnId");
        xmlWriter.writeElementString("BIC", "HSBCCNSH");
        //地址
        xmlWriter.writeStartElement("PstlAdr");
        xmlWriter.writeElementString("Ctry", "CN");
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        xmlWriter.writeEndElement();
        while (p_req1988.readRecord()){
            //收款方交易信息
            xmlWriter.writeStartElement("CdtTrfTxInf");
            xmlWriter.writeStartElement("PmtId");
            xmlWriter.writeElementString("InstrId", p_req1988.readedDetail.askNumber);
            xmlWriter.writeElementString("EndToEndId", p_req1988.readedDetail.askNumber);
            xmlWriter.writeEndElement();
            xmlWriter.writeStartElement("Amt");
            String currency = convertCurToBank(p_req1988.readedDetail.recCur);
            xmlWriter.writeElementAttribute("InstdAmt",p_req1988.readedDetail.payAmount,"Ccy",currency);
            xmlWriter.writeEndElement();
            xmlWriter.writeElementStringNotNull("ChrgBr", "DEBT");
            //收款人银行信息
            xmlWriter.writeStartElement("CdtrAgt");
            xmlWriter.writeStartElement("FinInstnId");
            if(StringHelper.hasAnyChar(p_req1988.readedDetail.recSwiftCode)){
                xmlWriter.writeElementString("BIC", p_req1988.readedDetail.recSwiftCode);
            }
            String recBnkName=p_req1988.readedDetail.cnapsName;
            if(recBnkName.length()>140){
                recBnkName=recBnkName.substring(0,140);
            }
            xmlWriter.writeElementString("Nm", recBnkName);
            //地址
            xmlWriter.writeStartElement("PstlAdr");
            xmlWriter.writeElementString("Ctry", "CN");
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            //收款人信息
            xmlWriter.writeStartElement("Cdtr");
            xmlWriter.writeElementString("Nm", p_req1988.readedDetail.recName);
            //地址
            xmlWriter.writeStartElement("PstlAdr");
            xmlWriter.writeElementString("Ctry", "CN");
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            xmlWriter.writeStartElement("CdtrAcct");
            xmlWriter.writeStartElement("Id");
            xmlWriter.writeStartElement("Othr");
            xmlWriter.writeElementString("Id", p_req1988.readedDetail.recAct);
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            xmlWriter.writeEndElement();
            String ustrd=p_req1988.readedDetail.purpose;//用途
            if(StringHelper.hasAnyChar(ustrd)){
                xmlWriter.writeStartElement("RmtInf");
                xmlWriter.writeElementString("Ustrd",ustrd);
                xmlWriter.writeEndElement();
            }
            xmlWriter.writeEndElement();
        }
        xmlWriter.writeEndDocument();
    }

    /**
     * 地址处理
     * @param xmlWriter
     * @param address
     * @param countryCode
     */
    private void addressDealWith(XmlTextWriter xmlWriter, String address,String countryCode,StringBuilder addLine){
        String twnNm="";
        if(StringHelper.hasAnyChar(address)){
            //解析地址和城镇信息
            String addr=address.contains("##")?address.substring(0,address.indexOf("##")):address;
            String trwn=address.contains("##")?address.substring(address.indexOf("##")+2).replaceAll("##"," "):"";
            //拼接获取长度
            String payAddr=new StringBuilder(trwn).append(" ").append(addr).toString();
            if(StringHelper.hasAnyChar(payAddr)){
                if(payAddr.length()>35){
                    twnNm=payAddr.substring(0,35);
                    addLine.append(payAddr.substring(35));
                }else {
                    twnNm=payAddr;
                }
            }
        }
        xmlWriter.writeStartElement("PstlAdr");
        if(StringHelper.hasAnyChar(twnNm)){
            xmlWriter.writeElementString("TwnNm", twnNm);
        }
        if(StringHelper.hasAnyChar(countryCode)){
            xmlWriter.writeElementString("CtrySubDvsn", "C".equals(countryCode)?"CN":countryCode);
            xmlWriter.writeElementString("Ctry", "C".equals(countryCode)?"CN":countryCode);
        }
        if(StringHelper.hasAnyChar(addLine.toString())){
            if(addLine.length()>35){
                xmlWriter.writeElementString("AdrLine", addLine.toString().substring(0,35));
            }else {
                xmlWriter.writeElementString("AdrLine", addLine.toString());
            }
        }
        xmlWriter.writeEndElement();
    }

    protected String FeeBearer(String costmode){
        String chrgBr="";
        if("OUR".equals(costmode)){
            chrgBr="DEBT";
        }else if("BEN".equals(costmode)){
            chrgBr="CRED";
        }else if("SHA".equals(costmode)){
            chrgBr="SHAR";
        }
        return chrgBr;
    }

    /**
     * 获取ack状态并写入文件
     * @param ackFilePath
     * @param payDate
     * @param rspStatus
     * @return
     * @throws Exception
     */
    protected void getAckStatus(String ackFilePath,String payDate,String[] rspStatus,String level) throws Exception{
        String ackFile=ackFilePath+File.separator+payDate+File.separator
                + "ACK"+File.separator +rspStatus[0]+File.separator+rspStatus[0]+"_"+level+".txt";
        String contents=rspStatus[0]+"|"+rspStatus[1]+"|"+rspStatus[2]+"|";
        //写入文件
        FileHelper.appendFile(ackFile, contents, getCharset());
    }

    /**
     * 获取支持的查询日期
     * @param sDate
     * @param eDate
     * @return
     */
    protected String[] getQueryDate(String sDate,String eDate) throws Exception{
        String[] dateAry=new String[]{sDate,eDate};
        String hisTransSupDate=getBankConfig().getValueAsString("hisTransSupDate");
        //增加历史明细支持查询日期
        if (StringHelper.hasAnyChar(hisTransSupDate) && hisTransSupDate.length() == 8) {
            //判断起始日
            Date avaiDate = Format.Date8Format.parse(hisTransSupDate);
            Date startDate = Format.Date8Format.parse(dateAry[0]);
            Date endDate = Format.Date8Format.parse(dateAry[1]);
            if (endDate.after(avaiDate)) {
                if (startDate.before(avaiDate)) {
                    dateAry[0] = hisTransSupDate;
                }
            } else {
                dateAry[0] = hisTransSupDate;
                dateAry[1] = hisTransSupDate;
            }
        }
        return dateAry;
    }
}
